package cn.pconline.autoclub.service;

import cn.pconline.autoclub.config.SystemConfig;
import cn.pconline.autoclub.entity.ClubForum;
import cn.pconline.autoclub.entity.User;
import cn.pconline.autoclub.util.DateUtils;
import cn.pconline.r.client.EntityBuilder;
import cn.pconline.r.client.RClient;
import cn.pconline.r.client.ResponseExtractor;
import cn.pconline.r.client.SimpleHttpTemplate;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.StatusLine;
import org.apache.http.util.EntityUtils;
import org.gelivable.web.EnvUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.util.HtmlUtils;

/**
 * @author 作者 guoqiang
 * @version 2014-2-8
 */
public class IntfService {

    /**
     * refererUri
     */
    private String refererUri = "http://bbs.pcauto.com.cn/";
    private static final Logger log = LoggerFactory.getLogger(IntfService.class);
    @Autowired
    private SystemConfig systemConfig;
    @Autowired
    private SimpleHttpTemplate simpleHttpTemplate;

    /**
     *
     * @param topIds
     * @return 根据贴ID获取主题内容
     */
    public JSONArray getBbsTxtJSON(long topIds) {
        if (topIds < 1) {
            return null;
        }
        StringBuilder url = new StringBuilder(128);
        RClient rClient = EnvUtils.getEnv().getBean(RClient.class);
        String bbsUrl = EnvUtils.getEnv().getBean(SystemConfig.class).getBbsRoot();
        url.append(bbsUrl).append("/intf/_topics_id.jsp?ids=").append(topIds);
        url.append("&callback=json&ignoreXSS=true&passEm=true");
        String result = rClient.get(url.toString(), refererUri, 5, TimeUnit.MINUTES);
        JSONArray json = null;
        if (StringUtils.isNotBlank(result)) {
            try {
                json = JSON.parseArray(result.toString());
            } catch (Exception e) {
                log.error("格式化JSON失败,调用论坛接口：" + url.toString(), e);
            }
        }
        return json;
    }

    public JSONObject bindPhone(String phone, String code, String commonSessionId) {
        String relUrl = systemConfig.getRoot() + "/ClubController.found.bindPhone";
        String url = systemConfig.getBindPhoneUrl();
        String result = simpleHttpTemplate.post(url, relUrl, null,
                new ResponseExtractor<String>() {
                    @Override
                    public String extractData(HttpResponse response) {
                        StatusLine statusLine = response.getStatusLine();
                        if (statusLine.getStatusCode() == 200) {
                            try {
                                return EntityUtils.toString(response.getEntity());
                            } catch (IOException ex) {
                                log.error("bindPhone fail 1!", ex);
                            } catch (ParseException ex) {
                                log.error("bindPhone fail 2!", ex);
                            }
                        } else {
                            log.error("bindPhone fail statusCode is " + statusLine.getStatusCode());
                            try {
                                log.error(EntityUtils.toString(response.getEntity()));
                            } catch (IOException ex) {
                                log.error("bindPhone fail--IOException!", ex);
                            } catch (ParseException ex) {
                                log.error("bindPhone fail--ParseException!", ex);
                            }
                        }
                        return null;
                    }
                },
                EntityBuilder.entity().param("act", "bind").param("mobile", phone).param("verificationCode", code)
                .param(systemConfig.getUserSessionName(), commonSessionId).build(), 3000);
        JSONObject rs = JSONObject.parseObject(result);
        return rs;
    }

    /**
     * 根据ip获取省市json数据
     *
     * @param ip
     * @return
     */
    public JSONObject getPlaceByIp(String ip) {
        if (StringUtils.isBlank(ip)) {
            return null;
        }
        StringBuilder url = new StringBuilder(128);
        RClient rClient = EnvUtils.getEnv().getBean(RClient.class);
        String ucUrl = EnvUtils.getEnv().getBean(SystemConfig.class).getUcRoot();
        url.append(ucUrl).append("/intf/getAreaIdByIp.jsp?ip=").append(ip);
        String result = rClient.get(url.toString(), refererUri, 5, TimeUnit.MINUTES);
        JSONObject json = null;
        if (StringUtils.isNotBlank(result)) {
            try {
                json = JSON.parseObject(result.toString());
            } catch (Exception e) {
                log.error("格式化JSON失败,调用论坛接口：" + url.toString(), e);
            }
        }
        return json;
    }

    public JSONObject getPlaceByIpFromWhois(String ip) {
        if (StringUtils.isBlank(ip)) {
            return null;
        }
        StringBuilder url = new StringBuilder(128);
        RClient rClient = EnvUtils.getEnv().getBean(RClient.class);
        String whoisUrl = EnvUtils.getEnv().getBean(SystemConfig.class).getWhoisRoot();
        url.append(whoisUrl).append("/ipJson.jsp?json=true&ip=").append(ip);
        String result = rClient.get(url.toString(), refererUri, 5, TimeUnit.SECONDS);
        if (StringUtils.isNotBlank(result)) {
            try {
                return JSON.parseObject(result.toString());
            } catch (Exception e) {
                log.error("格式化JSON失败,调用ip库接口：" + url.toString(), e);
            }
        } else {
            log.error("get palce failed from whois. url: {}, result: {}", url, result);
        }
        return new JSONObject();
    }

    /**
     * 根据经纬度获取地址
     *
     * @param longitude
     * @param latitude
     * @return
     */
    public JSONObject getPlaceByLngLli(double longitude, double latitude) {
        StringBuilder url = new StringBuilder();
        RClient rClient = EnvUtils.getEnv().getBean(RClient.class);
        String whoisUrl = EnvUtils.getEnv().getBean(SystemConfig.class).getWhoisRoot();
        url.append(whoisUrl).append("/ipAreaCoordJson.jsp?json=true&coords=").append(longitude).append(",").append(latitude);
        String result = rClient.get(url.toString(), "", 5, TimeUnit.SECONDS);
        if (StringUtils.isNotBlank(result)) {
            try {
                return JSON.parseObject(result.toString());
            } catch (Exception e) {
                log.error("change JSON Format fail ,url :{}" + url.toString(), e);
            }
        } else {
            log.error("get palce failed from whois. url: {}, result: {}", url, result);
        }
        return new JSONObject();
    }

    /**
     *
     * @param province
     * @param city
     * @param code
     * @param commonSessionId
     * @param commonSessionId1
     */
    public void checkProvinceCity(long provinceId, long cityId, long loginId, String code, String cookie) {
        String relUrl = systemConfig.getRoot() + "/UserController.apply.applyMembership";
        String url = systemConfig.getUcRoot() + "/setting/profile_club.jsp";
        String result = simpleHttpTemplate.post(url, relUrl, null,
                new ResponseExtractor<String>() {
                    @Override
                    public String extractData(HttpResponse response) {
                        StatusLine statusLine = response.getStatusLine();
                        if (statusLine.getStatusCode() == 200) {
                            try {
                                return EntityUtils.toString(response.getEntity());
                            } catch (IOException ex) {
                                log.error("checkBrandSerial fail 1!", ex);
                            } catch (ParseException ex) {
                                log.error("checkBrandSerial fail 2!", ex);
                            }
                        } else {
                            log.error("checkProvinceCity fail statusCode is " + statusLine.getStatusCode());
                            try {
                                log.error(EntityUtils.toString(response.getEntity()));
                            } catch (IOException ex) {
                                log.error("checkBrandSerial fail--IOException!", ex);
                            } catch (ParseException ex) {
                                log.error("checkBrandSerial fail--ParseException!", ex);
                            }
                        }
                        return null;
                    }
                },
                EntityBuilder.entity().param("act", "save").param("loginId", loginId).param("domicileId", cityId).param(code, cookie).build(), 3000);
        JSONObject rs = JSONObject.parseObject(result);
        int c = rs.getIntValue("code");
        if (c == -1) {
            log.error("同步省市信息失败！" + rs.getString("message"));
        }
    }

    /**
     *
     * @param brand
     * @param serial
     * @param commonSessionId
     * @param commonSessionId1
     */
    public void checkBrandSerial(int brand, int serial, String code, String cookie) {
        String relUrl = systemConfig.getRoot() + "/UserController.apply.applyMembership";
        String url = systemConfig.getUcRoot() + "/intf/modifyCar.jsp";
        String result = simpleHttpTemplate.post(url, relUrl, null,
                new ResponseExtractor<String>() {
                    @Override
                    public String extractData(HttpResponse response) {
                        StatusLine statusLine = response.getStatusLine();
                        if (statusLine.getStatusCode() == 200) {
                            try {
                                return EntityUtils.toString(response.getEntity());
                            } catch (IOException ex) {
                                log.error("checkBrandSerial fail 1!", ex);
                            } catch (ParseException ex) {
                                log.error("checkBrandSerial fail 2!", ex);
                            }
                        } else {
                            log.error("checkBrandSerial fail statusCode is " + statusLine.getStatusCode());
                            try {
                                log.error(EntityUtils.toString(response.getEntity()));
                            } catch (IOException ex) {
                                log.error("checkBrandSerial fail--IOException!", ex);
                            } catch (ParseException ex) {
                                log.error("checkBrandSerial fail--ParseException!", ex);
                            }
                        }
                        return null;
                    }
                },
                EntityBuilder.entity().param("act", "save").param("series", serial).param(code, cookie).build(), 3000);
        JSONObject rs = JSONObject.parseObject(result);
        if (rs != null) {
            int c = rs.getIntValue("code");
            if (c == -1) {
                log.error("同步车系车型信息失败！" + rs.getString("message"));
            }
        }
    }

    /**
     * 根据用户ID获取精华帖接口
     *
     * @param userId
     * @return
     */
    public JSONObject getPickByUserId(long userId) {
        StringBuilder url = new StringBuilder(128);
        RClient rClient = EnvUtils.getEnv().getBean(RClient.class);
        String bbsUrl = EnvUtils.getEnv().getBean(SystemConfig.class).getBbsRoot();
        url.append(bbsUrl).append("/intf/user/_picks.jsp?userId=").append(userId);
        url.append("&pageSize=1000");
        url.append("&needImages=1");//把精华帖子的图片同步到车友会
        String result = rClient.get(url.toString(), refererUri, 5, TimeUnit.MINUTES);
        JSONObject json = null;
        if (StringUtils.isNotBlank(result)) {
            try {
                json = JSON.parseObject(result.toString());
            } catch (Exception e) {
                log.error("格式化JSON失败,调用论坛接口：" + url.toString(), e);
            }
        }
        return json;
    }

    /**
     * 根据用户id获取用户昵称
     *
     * @param uid
     * @return
     */
    public String getNickNameByUserId(long uid) {
        RClient rClient = EnvUtils.getEnv().getBean(RClient.class);
        String ucRoot = EnvUtils.getEnv().getBean(SystemConfig.class).getUcRoot();
        String nickname = "";
        String ja = "";
        try {
            ja = rClient.get(ucRoot + "/intf/client/getUser.jsp?id=" + uid, null, 1, TimeUnit.SECONDS);
            JSONObject jo = JSONObject.parseObject(ja);
            if (jo == null) {
                return nickname;
            }
            nickname = jo.getString("nickName");
            nickname = HtmlUtils.htmlUnescape(nickname);//从个人中心拿到的数据可能有转义，这里还原回去
        } catch (Exception e) {
            log.error("Retrieve nickname error:uid: {}, result: {}", uid, ja);
            log.error("Retrieve nickname error", e);
        }
        return nickname;
    }

    /**
     * 同步个人资料到个人中心
     *
     * @param commonSessionId 用户登录ID
     * @param user
     * @param realName 真实姓名
     * @param gender 性别
     * @param telephone 电话
     * @param postCode 邮编
     * @param address 地址
     * @param domicileId 城市ID
     * @return
     */
    public String updateUserCenter(String commonSessionId, String realName, String nickName, int gender, String telephone,
            String postCode, String address, long domicileId, String birthday) {
        Map<String, Object> params = new HashMap<String, Object>();
        if (realName != null) {
            params.put("realName", realName);
        }
        if (nickName != null) {
            params.put("nickName", nickName);
        }
        if (telephone != null) {
            params.put("telephone", telephone);
        }
        if (postCode != null) {
            params.put("postCode", postCode);
        }
        if (address != null) {
            params.put("address", address);
        }
        if (gender == User.CLUB_MALE || gender == User.CLUB_FEMALE) {
            params.put("gender", gender == User.CLUB_MALE ? User.MALE : User.FEMALE);//车友会（0：男，1:女），个人中心（1：男，2：女）
        }
        //省市同步，只传 cityId即可，如果没有cityId,传provinceId; 如果都没有，不同步
        if (domicileId > 0) {
            params.put("domicileId", domicileId);//城市ID
        }
        if (birthday != null) {
            params.put("birthday", birthday);
        }
        params.put("act", "save");
        params.put(systemConfig.getUserSessionName(), commonSessionId);
        String ucRoot = systemConfig.getUcRoot();
        String result = simpleHttpTemplate.post(ucRoot + "/intf/club/updateUser.jsp", null, new ResponseExtractor<String>() {
            @Override
            public String extractData(HttpResponse response) throws IOException {
                StatusLine statusLine = response.getStatusLine();
                if (statusLine.getStatusCode() == 200) {
                    try {
                        return EntityUtils.toString(response.getEntity());
                    } catch (IOException ex) {
                        log.error("sendToMyCenter fail 1!", ex);
                    } catch (ParseException ex) {
                        log.error("sendToMyCenter fail 2!", ex);
                    }
                } else {
                    log.error("sendToMyCenter fail statusCode is " + statusLine.getStatusCode());
                    try {
                        log.error(EntityUtils.toString(response.getEntity()));
                    } catch (IOException ex) {
                        log.error("sendToMyCenter fail--IOException", ex);
                    } catch (ParseException ex) {
                        log.error("sendToMyCenter fail--ParseException", ex);
                    }
                }
                return "";
            }
        }, EntityBuilder.entity().params(params).build());
        return result;
    }

    public JSONObject findForumFromBbs(long ids) {
        String relUrl = systemConfig.getRoot() + "/AdminOClubController.find.findForum";
        String url = systemConfig.getBbsRoot() + "/intf/forums.do?fids=" + ids;
        RClient rClient = EnvUtils.getEnv().getBean(RClient.class);
        String result = rClient.get(url, relUrl, 3000, TimeUnit.MINUTES);
        try {
            JSONArray obj = JSONArray.parseArray(result);
            if (obj != null && obj.size() > 0) {
                return obj.getJSONObject(0);
            }
            return null;
        } catch (Exception ex) {
            log.error("获取论坛版块出错:" + result);
            return null;
        }
    }

    private ClubForum getClubForum(JSONObject obj, int seq, int type) {
        ClubForum f = new ClubForum();
        f.setForumId(obj.getLongValue("fid"));
        f.setPopulation(obj.getLongValue("postCount"));
        f.setSeq(seq);
        f.setTitle(obj.getString("forumName"));
        f.setUpdateAt(DateUtils.getNow());
        f.setUrl(obj.getString("forumUrl"));
        f.setIcon(obj.getString("icon"));
        f.setType(type);
        return f;
    }

    /**
     * 通过接口获取版块信息（车系版块和地区版块）
     *
     * @param brandId
     * @param serialId
     * @param provinceId
     * @param cityId
     * @return
     */
    public List<ClubForum> listClubForums(long brandId, long serialId, long provinceId, long cityId) {
        List<ClubForum> list = new ArrayList<ClubForum>();
        String relUrl = systemConfig.getRoot() + "/IntfService.getClubForum";
        String seriesUrl = systemConfig.getBbsRoot() + "/intf/getForumByCarSeries.do?";
        seriesUrl += "brandId=" + brandId;
        seriesUrl += "&seriesId=" + serialId;
        String cityUrl = systemConfig.getBbsRoot() + "/intf/getForumByArea.do?";
        cityUrl += "cityId=" + cityId;
        cityUrl += "&provinceId=" + provinceId;
        JSONObject seriesRs = JSONObject.parseObject(simpleHttpTemplate.get(seriesUrl, relUrl));
        JSONObject cityRs = JSONObject.parseObject(simpleHttpTemplate.get(cityUrl, relUrl));
        if (seriesRs == null || cityRs == null) {
            log.error("addClubForum fail!maybe network problum!");
            log.error("seriesUrl:" + seriesUrl);
            log.error("cityUrl:" + cityUrl);
            return list;
        }
        JSONObject seriesForum = seriesRs.getJSONObject("seriesForum");
        JSONObject brandForum = seriesRs.getJSONObject("brandForum");
        JSONObject cityForum = cityRs.getJSONObject("cityForum");
        JSONObject provinceForum = cityRs.getJSONObject("provinceForum");
        int seq = 1;
        if (seriesForum != null) {
            ClubForum f = getClubForum(seriesForum, seq++, ClubForum.TYPE_SERIAL);
            list.add(f);
        } else if (brandForum != null) {
            ClubForum f = getClubForum(brandForum, seq++, ClubForum.TYPE_SERIAL);
            list.add(f);
        }
        if (cityForum != null) {
            ClubForum f = getClubForum(cityForum, seq++, ClubForum.TYPE_AREA);
            list.add(f);
        } else if (provinceForum != null) {
            ClubForum f = getClubForum(provinceForum, seq++, ClubForum.TYPE_AREA);
            list.add(f);
        }
        return list;
    }
    /**
     * 批量获取论坛版块信息
     * @param forumId
     * @return 
     */
    public JSONArray getForumByForumIds(Long[] forumIds){
        if(forumIds ==null || forumIds.length == 0){
            return null;
        }
        String relUrl = systemConfig.getRoot() + "/IntfService.getForumNameByForumId";
        String rootUrl =systemConfig.getBbsRoot()+"/appapi/1/forum/findForumsByIds.do?";
        String ids = StringUtils.join(forumIds,",");
        String url = rootUrl+"fids="+ids;
        JSONObject object = JSONObject.parseObject(simpleHttpTemplate.get(url, relUrl));
        if(object == null || object.getIntValue("code")==-1){
            log.error("find forumId fail! forumIds :"+ids);
            return null;
        }
        JSONArray forumList = object.getJSONArray("forumList");
        if(forumList != null && forumList.size()>0){
           return forumList;
        }
        return null;
    }
}
